Maxsus istisno ishlovchilari yordamida FastAPI xatoliklarini boshqarishni o'zlashtiring. Yaxshiroq foydalanuvchi tajribasi uchun oqlangan xato javoblari bilan mustahkam API'larni qanday yaratishni o'rganing.
Python FastAPI Xatoliklarni boshqarish: Mustahkam maxsus istisno ishlovchilarini yaratish
Xatoliklarni boshqarish mustahkam va ishonchli API'larni yaratishning muhim jihatidir. Python'ning FastAPI-da siz xatolarni oqlangan tarzda boshqarish va mijozlarga ma'lumotli javoblar berish uchun maxsus istisno ishlovchilaridan foydalanishingiz mumkin. Ushbu blog posti sizni FastAPI-da maxsus istisno ishlovchilarini yaratish jarayonida boshqaradi, bu sizga yanada chidamli va foydalanuvchilar uchun qulay ilovalarni yaratishga imkon beradi.
Nima uchun maxsus istisno ishlovchilari?
FastAPI istisnolarni boshqarish uchun o'rnatilgan yordamni taqdim etadi. Biroq, faqat standart xato javoblariga tayanib, mijozlarga noaniq yoki foydasiz ma'lumot qoldirishi mumkin. Maxsus istisno ishlovchilari bir qancha afzalliklarni taklif qiladi:
- Yaxshilangan foydalanuvchi tajribasi: Muayyan xato stsenariylariga moslashtirilgan aniq va informativ xato xabarlarini taqdim eting.
- Markazlashtirilgan xatolarni boshqarish: Kodni yanada texnik jihatdan qulayroq qilish uchun xatolarni boshqarish mantiqini bir joyga birlashtiring.
- Izchil xato javoblari: Xato javoblari izchil formatga rioya qilishini ta'minlang, bu API-dan foydalanishni yaxshilaydi.
- Xavfsizlikni yaxshilash: Xato xabarlarida maxfiy ma'lumotlarning oshkor etilishining oldini oling.
- Maxsus jurnal: Nosozliklarni bartaraf etish va monitoring maqsadida xato haqidagi batafsil ma'lumotlarni jurnalga yozing.
FastAPI'ning istisnolarni boshqarishni tushunish
FastAPI xatolarni boshqarish uchun Python'ning o'rnatilgan istisnolarni boshqarish mexanizmlari va o'z bog'liqlik in'ektsiyasi tizimining kombinatsiyasidan foydalanadi. Marshrut yoki bog'liqlik ichida istisno paydo bo'lganda, FastAPI uni qayta ishlash uchun tegishli istisno ishlovchisini qidiradi.
Istisno ishlovchilari @app.exception_handler() bilan bezatilgan, ikkita dalilni qabul qiladigan funksiyalardir: istisno turi va so'rov ob'ekti. Ishlovchi tegishli HTTP javobini qaytarish uchun javobgardir.
Maxsus istisnolarni yaratish
Maxsus istisno ishlovchilarini belgilashdan oldin, odatda, ilovangizdagi ma'lum xato shartlarini ifodalovchi maxsus istisno sinflarini yaratish foydalidir. Bu kodning o'qilishini yaxshilaydi va turli xil xatolarni boshqarishni osonlashtiradi.
Misol uchun, siz elektron tijorat API-ni yaratayotganingizni va mahsulot omborda yo'qligi holatlarini boshqarishingiz kerakligini aytaylik. Siz OutOfStockError deb nomlangan maxsus istisno sinfini belgilashingiz mumkin:
class OutOfStockError(Exception):
def __init__(self, product_id: int):
self.product_id = product_id
self.message = f"Mahsulot {product_id} ID-ga ega omborda yo'q."
Ushbu maxsus istisno sinfi asosiy Exception sinfidan meros oladi va product_id atributi va maxsus xato xabarini o'z ichiga oladi.
Maxsus istisno ishlovchilarini amalga oshirish
Endi, keling, OutOfStockError uchun maxsus istisno ishlovchisini yarating. Ushbu ishlovchi istisnoni ushlaydi va xato xabarini o'z ichiga olgan JSON tanasi bilan HTTP 400 (Noto'g'ri so'rov) javobini qaytaradi.
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
app = FastAPI()
class OutOfStockError(Exception):
def __init__(self, product_id: int):
self.product_id = product_id
self.message = f"Mahsulot {product_id} ID-ga ega omborda yo'q."
@app.exception_handler(OutOfStockError)
async def out_of_stock_exception_handler(request: Request, exc: OutOfStockError):
return JSONResponse(
status_code=400,
content={"message": exc.message},
)
@app.get("/products/{product_id}")
async def get_product(product_id: int):
# Mahsulot zaxirasini simulyatsiya qilish
if product_id == 123:
raise OutOfStockError(product_id=product_id)
return {"product_id": product_id, "name": "Misol mahsulot", "price": 29.99}
Ushbu misolda, @app.exception_handler(OutOfStockError) dekoratori out_of_stock_exception_handler funktsiyasini OutOfStockError istisnolarini boshqarish uchun ro'yxatdan o'tkazadi. OutOfStockError get_product marshrutida ko'tarilganda, istisno ishlovchisi chaqiriladi. Ishlovchi keyin 400 holat kodi va xato xabarini o'z ichiga olgan JSON tanasi bilan JSONResponse ni qaytaradi.
Ko'p istisno turlarini boshqarish
Turli xil turdagi istisnolarni boshqarish uchun bir nechta istisno ishlovchilarini belgilashingiz mumkin. Misol uchun, foydalanuvchi kiritilganini tahlil qilishda yuzaga keladigan ValueError istisnolarini boshqarmoqchi bo'lishingiz mumkin.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(ValueError)
async def value_error_exception_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=400,
content={"message": str(exc)},
)
@app.get("/items/{item_id}")
async def get_item(item_id: int):
# Yaroqsiz item_id ni simulyatsiya qilish
if item_id < 0:
raise ValueError("Mahsulot IDsi musbat butun son bo'lishi kerak.")
return {"item_id": item_id, "name": "Misol mahsulot"}
Ushbu misolda, value_error_exception_handler funktsiyasi ValueError istisnolarini boshqaradi. U istisno ob'ektidan xato xabarini chiqaradi va uni JSON javobida qaytaradi.
HTTPException-dan foydalanish
FastAPI HTTP-ga xos xatolarni ko'tarish uchun ishlatilishi mumkin bo'lgan HTTPException deb nomlangan o'rnatilgan istisno sinfini taqdim etadi. Bu ruxsatsiz kirish yoki resurs topilmagan kabi umumiy xato stsenariylarini boshqarish uchun foydali bo'lishi mumkin.
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
# Foydalanuvchi topilmadi simulyatsiya qilish
if user_id == 999:
raise HTTPException(status_code=404, detail="Foydalanuvchi topilmadi")
return {"user_id": user_id, "name": "Misol foydalanuvchi"}
Ushbu misolda, HTTPException 404 (Topilmadi) holat kodi va batafsil xabar bilan ko'tariladi. FastAPI avtomatik ravishda HTTPException istisnolarini boshqaradi va ko'rsatilgan holat kodi va batafsil xabar bilan JSON javobini qaytaradi.
Global istisno ishlovchilari
Siz, shuningdek, boshqa istisno ishlovchilari tomonidan boshqarilmaydigan barcha istisnolarni ushlaydigan global istisno ishlovchilarini belgilashingiz mumkin. Bu xatolarni ro'yxatga olish yoki mijozga umumiy xato xabarini qaytarish uchun foydali bo'lishi mumkin.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logger = logging.getLogger(__name__)
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
logger.exception(f"Boshqarilmagan istisno: {exc}")
return JSONResponse(
status_code=500,
content={"message": "Server ichki xatosi"},
)
@app.get("/error")
async def trigger_error():
raise ValueError("Bu sinov xatosi.")
Ushbu misolda, global_exception_handler funktsiyasi boshqa istisno ishlovchilari tomonidan boshqarilmaydigan barcha istisnolarni boshqaradi. U xatoni jurnalga yozadi va umumiy xato xabari bilan 500 (Ichki server xatosi) javobini qaytaradi.
Istisnolarni boshqarish uchun o'rta dasturdan foydalanish
Istisnolarni boshqarishning yana bir usuli - o'rta dasturdan foydalanish. O'rta dastur funktsiyalari har bir so'rovdan oldin va keyin bajariladi, bu sizga istisnolarni yuqori darajada ushlab turishga va boshqarishga imkon beradi. Bu so'rovlar va javoblarni jurnalga yozish yoki maxsus autentifikatsiya yoki avtorizatsiya mantig'ini amalga oshirish kabi vazifalar uchun foydali bo'lishi mumkin.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logger = logging.getLogger(__name__)
@app.middleware("http")
async def exception_middleware(request: Request, call_next):
try:
response = await call_next(request)
except Exception as exc:
logger.exception(f"Boshqarilmagan istisno: {exc}")
return JSONResponse(
status_code=500,
content={"message": "Server ichki xatosi"},
)
return response
@app.get("/error")
async def trigger_error():
raise ValueError("Bu sinov xatosi.")
Ushbu misolda, exception_middleware funktsiyasi so'rovni qayta ishlash mantig'ini try...except blokiga o'raydi. Agar so'rovni qayta ishlash paytida istisno yuzaga kelsa, o'rta dastur xatoni jurnalga yozadi va 500 (Ichki server xatosi) javobini qaytaradi.
Misol: Xalqarolashtirish (i18n) va xato xabarlari
Global auditoriya uchun API'larni yaratishda xato xabarlarini xalqarolashtirishni ko'rib chiqing. Bu foydalanuvchining mintaqasiga qarab turli tillarda xato xabarlarini taqdim etishni o'z ichiga oladi. To'liq i18n-ni amalga oshirish ushbu maqolaning doirasidan tashqarida bo'lsa-da, kontseptsiyani ko'rsatadigan soddalashtirilgan misol keltiraylik:
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from typing import Dict
app = FastAPI()
# Mock tarjima lug'ati (haqiqiy i18n kutubxonasini almashtiring)
translations: Dict[str, Dict[str, str]] = {
"en": {
"product_not_found": "Mahsulot {product_id} ID bilan topilmadi.",
"invalid_input": "Yaroqsiz kiritish: {error_message}",
},
"fr": {
"product_not_found": "Mahsulot {product_id} bilan topilmadi.",
"invalid_input": "Yaroqsiz kirish: {error_message}",
},
"es": {
"product_not_found": "Mahsulot {product_id} bilan topilmadi.",
"invalid_input": "Yaroqsiz kirish: {error_message}",
},
"de": {
"product_not_found": "Mahsulot {product_id} bilan topilmadi.",
"invalid_input": "Yaroqsiz kirish: {error_message}",
}
}
def get_translation(locale: str, key: str, **kwargs) -> str:
"""Berilgan mahalliy va kalit uchun tarjimani oladi.
Agar joy yoki kalit topilmasa, standart xabar qaytaradi.
"""
if locale in translations and key in translations[locale]:
return translations[locale][key].format(**kwargs)
return f"Mahalliy '{locale}'da kalit uchun tarjima yo'q '{key}'."
@app.get("/products/{product_id}")
async def get_product(request: Request, product_id: int, locale: str = "en"):
# Mahsulotni qidirishni simulyatsiya qilish
if product_id > 100:
message = get_translation(locale, "product_not_found", product_id=product_id)
raise HTTPException(status_code=404, detail=message)
if product_id < 0:
message = get_translation(locale, "invalid_input", error_message="Mahsulot IDsi musbat bo'lishi kerak")
raise HTTPException(status_code=400, detail=message)
return {"product_id": product_id, "name": "Misol mahsulot"}
i18n misoli uchun asosiy takomillashtirishlar:
- Mahalliy parametr: Marshrut endi
localeso'rov parametrini qabul qiladi, bu mijozlarga o'zlarining afzal tilini belgilashga imkon beradi (standart sifatida "en" ingliz tili uchun). - Tarjima lug'ati:
translationslug'ati (mock) turli xil lokalalar (ingliz, frantsuz, ispan, nemis bu holatda) uchun xato xabarlarini saqlaydi. Haqiqiy dasturda siz maxsus i18n kutubxonasidan foydalanasiz. get_translationFunktsiyasi: Ushbu yordamchi funktsiyalocalevakeyasosida tegishli tarjimani oladi. U dinamik qiymatlarni (masalan,product_id) kiritish uchun satr formatlashni ham qo'llab-quvvatlaydi.- Dinamik xato xabarlari:
HTTPExceptionendiget_translationfunktsiyasi yordamida dinamik ravishda yaratilgandetailxabar bilan ko'tariladi.
Mijoz /products/101?locale=fr so'rovini yuborsa, ular frantsuz tilida xato xabarini oladi (agar tarjima mavjud bo'lsa). /products/-1?locale=es so'rovini yuborishda ular ispan tilida salbiy ID haqida xabar oladi (agar mavjud bo'lsa).
/products/200?locale=xx (tarjimalari bo'lmagan mahalliylashtirish) so'rovini yuborishda ular `Tarjima yo'q` xabarini oladi.
Xatolarni boshqarish bo'yicha eng yaxshi amaliyotlar
FastAPI-da xatolarni boshqarishni amalga oshirishda yodda tutish kerak bo'lgan ba'zi eng yaxshi amaliyotlar:
- Maxsus istisnolardan foydalaning: Ilojangizdagi ma'lum xato shartlarini ifodalash uchun maxsus istisno sinflarini belgilang.
- Informativ xato xabarlarini taqdim eting: Mijozlarga xatoning sababini tushunishga yordam beradigan aniq va ixcham xato xabarlarini o'z ichiga oling.
- Tegishli HTTP holat kodlaridan foydalaning: Xatoning xususiyatini aniq aks ettiruvchi HTTP holat kodlarini qaytaring. Misol uchun, yaroqsiz kiritish uchun 400 (Noto'g'ri so'rov), yo'qolgan resurslar uchun 404 (Topilmadi) va kutilmagan xatolar uchun 500 (Ichki server xatosi) dan foydalaning.
- Maxfiy ma'lumotlarni oshkor qilishdan saqlaning: Xato xabarlarida ma'lumotlar bazasi ma'lumotlari yoki API kalitlari kabi maxfiy ma'lumotlarni ochishdan ehtiyot bo'ling.
- Xatolarni jurnalga yozing: Nosozliklarni bartaraf etish va monitoring maqsadida xato haqidagi batafsil ma'lumotlarni jurnalga yozing. Python'ning o'rnatilgan
loggingmoduli kabi jurnal kutubxonasidan foydalaning. - Xatolarni boshqarish mantig'ini markazlashtiring: Xatolarni boshqarish mantig'ini bir joyga, masalan, maxsus istisno ishlovchilari yoki o'rta dasturlarga birlashtiring.
- Xatolarni boshqarishni sinab ko'ring: Xatolarni boshqarish mantig'ingiz to'g'ri ishlashini ta'minlash uchun birlik testlarini yozing.
- Maxsus xatolarni kuzatish xizmatidan foydalanishni ko'rib chiqing: Ishlab chiqarish muhitlari uchun xatolarni kuzatish va tahlil qilish uchun Sentry yoki Rollbar kabi maxsus xatolarni kuzatish xizmatidan foydalanishni ko'rib chiqing. Ushbu vositalar ilovangizning sog'lig'i haqida qimmatli ma'lumot berishi va muammolarni tezda aniqlashga va hal qilishga yordam berishi mumkin.
Xulosa
Maxsus istisno ishlovchilari FastAPI-da mustahkam va foydalanuvchilar uchun qulay API'larni yaratish uchun kuchli vositadir. Maxsus istisno sinflari va ishlovchilarini belgilash orqali siz xatolarni oqlangan tarzda boshqarishingiz, mijozlarga ma'lumotli javoblar berishingiz va ilovangizning umumiy ishonchliligi va texnik xizmatini yaxshilashingiz mumkin. Maxsus istisnolarni, HTTPExceptions'ni birlashtirish va qo'llaniladigan i18n tamoyillaridan foydalanish API'ni global muvaffaqiyatga erishtiradi.
Xatolarni boshqarish strategiyasini ishlab chiqishda foydalanuvchi tajribasini hisobga olishni unutmang. Foydalanuvchilarga muammoni tushunishga va uni qanday hal qilishga yordam beradigan aniq va ixcham xato xabarlarini taqdim eting. Samarali xatolarni boshqarish turli xil global auditoriya ehtiyojlarini qondiradigan yuqori sifatli API'larni yaratishning asosidir.